package fr.emse.tatiana.scoresheetvisualisation;

import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.Viewport;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;

import fr.emse.tatiana.graphical.DisplayRule;
import fr.emse.tatiana.replayable.IReplayableModel;
import fr.emse.tatiana.replayable.analysis.IAnalysis;
import fr.emse.tatiana.replayable.analysis.IGraphAnalysis;
import fr.emse.tatiana.replayable.analysis.Link;
import fr.emse.tatiana.replayable.analysis.graph.GraphAnalysisPartFactory;
import fr.emse.tatiana.scoresheetvisualisation.actions.ZoomInXAction;
import fr.emse.tatiana.scoresheetvisualisation.actions.ZoomOutXAction;


public class GraphicalDisplayEditor extends GraphicalEditorWithFlyoutPalette {
	
	IReplayableModel model;
	List<DisplayRule> rules;
	
	public GraphicalDisplayEditor(IReplayableModel model, List<DisplayRule> rules) {
		setEditDomain(new DefaultEditDomain(this));
		this.model=model;
		this.rules=rules;
	}
	
	@Override
	protected void configureGraphicalViewer() {
        super.configureGraphicalViewer();   
        GraphicalViewer viewer = getGraphicalViewer();
        viewer.setEditPartFactory(new DisplayPartFactory(rules));
        ScalableRootEditPart rootEditPart = new ScalableRootEditPart();
		viewer.setRootEditPart(rootEditPart);
		
		ContextMenuProvider provider = new ContextMenuProvider(viewer) {
			@Override
			public void buildContextMenu(IMenuManager menu) {
				menu.add(new ZoomInXAction(GraphicalDisplayEditor.this));
				menu.add(new ZoomOutXAction(GraphicalDisplayEditor.this));
			}
			
		};
		
		viewer.setContextMenu(provider);
//		ZoomManager zmanager = rootEditPart.getZoomManager();
//		getActionRegistry().registerAction(new ZoomInAction(zmanager));
//		getActionRegistry().registerAction(new ZoomOutAction(zmanager));
//		double[] zoomlevels = new double[]{0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0};
//		zmanager.setZoomLevels(zoomlevels);
//		zmanager.setZoom(2.0);
//		KeyHandler kh = new KeyHandler();
//		
//		kh.put(KeyStroke.getPressed('i',0),
//				getActionRegistry().getAction(GEFActionConstants.ZOOM_IN));
//		kh.put(KeyStroke.getPressed('o',0),
//				getActionRegistry().getAction(GEFActionConstants.ZOOM_OUT));
//		viewer.setKeyHandler(kh);
		
	}
	
	@Override
	public Object getAdapter(Class type) {
		if (type == ZoomManager.class) {
			return ((ScalableRootEditPart) 
					getGraphicalViewer().getRootEditPart()).getZoomManager();
		} else if (type == ReplayableModelPart.class) {
			return ((DisplayPartFactory)getViewer().getEditPartFactory()).getEditPart(model);
		} else
			return super.getAdapter(type);
	}


	@Override
	protected void initializeGraphicalViewer() {
		GraphicalViewer viewer = getGraphicalViewer();
		viewer.setContents(model);
		ReplayableModelPart part = (ReplayableModelPart)((DisplayPartFactory)viewer.getEditPartFactory()).getEditPart(model);
		part.setViewPort((Viewport) ((ScalableRootEditPart) viewer.getRootEditPart()).getFigure());
		this.refresh();
	}
	
	public GraphicalViewer getViewer() {
		return getGraphicalViewer();
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		// do nothing
	}

	public void setSelection(StructuredSelection modelsel) {
		List<EditPart> partlist = new Vector<EditPart>();
		List<Object> modelsellist = modelsel.toList();
		for (Object o: modelsellist) {
			EditPart part = ((DisplayPartFactory)getGraphicalViewer().getEditPartFactory()).getEditPart(o);
			if (part!=null) partlist.add(part);
		}
		IStructuredSelection partsel = StructuredSelection.EMPTY;
		if (partlist.size()>0) 
		{
			partsel = new StructuredSelection(partlist);
			getGraphicalViewer().reveal(partlist.get(0));
		}
		getGraphicalViewer().setSelection(partsel);
		
	}
	
	public void refresh() {
		EditPart part = ((DisplayPartFactory)getGraphicalViewer().getEditPartFactory()).getEditPart(model);
		part.refresh();
		for (IAnalysis a : model.getAnalyses()) {
			if (a instanceof IGraphAnalysis) {
				List<Link> links = ((IGraphAnalysis)a).getLinks(); 
				for (int i=0; i<links.size(); i++) {
					Link lk = links.get(i);
					EditPart linkpart = ((DisplayPartFactory)getGraphicalViewer().getEditPartFactory()).getEditPart(lk);
					if (linkpart!=null) linkpart.refresh();
				}
			}
		}
	}

	@Override
	protected PaletteRoot getPaletteRoot() {
		PaletteRoot root = new PaletteRoot();
		
		return root;
	}
	
}
